package com.gitee.wsl.coroutines


import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext


suspend fun groupJob(loads: List<GroupJob>){
    coroutineScope {
        for (load in loads) {
            val loadJob = launch { load.run() }
            val downstreams = loads.filter { load.id in it.dependsOnIds }
            for (downstream in downstreams) {
                downstream.upstreams += loadJob
            }
        }
    }
}

abstract class GroupJob(
    val applicationName: String,
    val id: String,
    val baseUrl: String?,
    val dependsOnIds: List<String>,
    val dispatcher: CoroutineDispatcher,
    val nowEpochMs: Long,
) {
    val upstreams = mutableListOf<Job>()

    /**
     * Fetch and receive ZiplineFile module.
     */
    suspend fun run() {
        _run()
        upstreams.joinAll()
        withContext(dispatcher) {
            _receive()
        }
    }

    abstract suspend fun _run()

    abstract suspend fun _receive()
}